﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PortalWeb.Areas.Admin.Controllers;
using PortalWeb.Areas.Admin.Models;
using PortalWeb.Common.UI;
using PortalWeb.Core.Entity;
using PortalWeb.Core.IManager;
using PortalWeb.Web.Filter;
using Quick.Common.Logging;

namespace PortalWeb.Web.Areas.Admin.Controllers
{
    [Navbar("菜单管理", "系统管理")]
    [CustomAuthorize]
    public class FunctionController : Controller
    {
        public FunctionController(IFunctionManager systemFunctionManager)
        {
            SystemFunctionManager = systemFunctionManager;
        }

        public IFunctionManager SystemFunctionManager { get; set; }

        // GET: Admin/Function
        [CustomAuthorize]
        public ActionResult Index()
        {
            return View();
        }

        [CustomAuthorize]
        public async Task<JsonResult> List(int? pId,string parentName, string sort = "Id", string order = "", int offset = 0,
            int limit = 10, string search = "")
        {
            List<object> list = new List<object>();
            try
            {
                var model =
                    from p in await SystemFunctionManager.LoadPageEntitiesAsync(
                        f => f.Name.Contains(search) && f.ParentId == pId,
                        order, sort, offset, limit)
                    select p;

                foreach (var p in model)
                {
                    list.Add(new
                    {
                        p.Id,
                        p.ParentId,
                        p.Name,
                        p.ActionUrl,
                        Order = p.Order.ToString("000"),
                        Type = p.Type.GetDescription(false),
                        Operator = p.OperatorUser.NickName,
                        OperationTime = p.OperationTime.ToShortDateString(),
                    });
                }

                var cs = await ActionHelper.GetControllersAsync(Assembly.GetExecutingAssembly());
                foreach (var p in cs)
                {
                    if (model.Any(m => m.ActionUrl == p.ActionUrl))
                        continue;
                    if (p.ParentName != parentName)
                        continue;
                    list.Add(new
                    {
                        Id = -1,
                        ParentId = pId,
                        p.Name,
                        p.ActionUrl,
                        Order = "000",
                        Type = EnumFunctionType.SystemFunction.GetDescription(false),
                        Operator = "",
                        OperationTime = "",
                    });
                }

                return Json(new {total = SystemFunctionManager.Count(), rows = list});
            }
            catch (Exception ex)
            {
                FileLogUtility.ErrorFormat("List", ex);
                return Json(new {error = ex.Message});
            }
        }

        public ActionResult Create(int? parentId)
        {
            return View(new EditFunctionViewModel {ParentId = parentId ?? 0});
        }

        [HttpPost, ActionName("Create")]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> CreateConfirmed(EditFunctionViewModel model)
        {
            if (ModelState.IsValid)
            {
                var function = new Function
                {
                    ParentId = model.ParentId,
                    Type = model.Type,
                    ActionUrl = model.ActionUrl,
                    Name = model.FunctionName,
                    Icon = model.Icon,
                    IsShow= true,
                    Operator = User.Identity.GetUserId(),
                    OperationTime = DateTime.Now
                };
                var result = await SystemFunctionManager.CreateAsync(function);
                if (result.Succeeded)
                {
                    string url = Url.Action("Index");
                    return Json(new { success = true, url = url });
                }
                AddErrors(result);
            }
            return View(model);
        }

        [Authorize(Roles = RoleConst.ADMINISTRATOR)]
        public async Task<ActionResult> Edit(int id, ManageMessageId? message)
        {
            var function = await SystemFunctionManager.GetAsync(id);
            var model = new EditFunctionViewModel(function);
            ViewBag.MessageId = message;
            return View(model);
        }


        [HttpPost, ActionName("Edit")]
        [Authorize(Roles = RoleConst.ADMINISTRATOR)]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> EditConfirmed(EditFunctionViewModel model)
        {
            if (ModelState.IsValid)
            {
                var function = new Function
                {
                    Id = model.Id,
                    ParentId = model.ParentId,
                    Type = model.Type,
                    Icon = model.Icon,
                    ActionUrl = model.ActionUrl,
                    Name = model.FunctionName,
                    Operator  = User.Identity.GetUserId(),
                    OperationTime = DateTime.Now
                };
                var result = await SystemFunctionManager.UpdateAsync(function);
                if (result.Succeeded)
                {
                    string url = Url.Action("Index");
                    return Json(new {success = true, url = url});
                }
                AddErrors(result);
            }
            return View(model);
        }

        [Authorize(Roles = RoleConst.ADMINISTRATOR)]
        public async Task<ActionResult> Deletes(int ids, ManageMessageId? message)
        {
            var function = await SystemFunctionManager.GetAsync(ids);
            var model = new DeleteFunctionViewModel(function);
            ViewBag.MessageId = message;
            return View("Delete",model);
        }

        [Authorize(Roles = RoleConst.ADMINISTRATOR)]
        public async Task<ActionResult> Delete(int id, ManageMessageId? message)
        {
            var function = await SystemFunctionManager.GetAsync(id);
            var model = new DeleteFunctionViewModel(function);
            ViewBag.MessageId = message;
            return View(model);
        }


        [HttpPost, ActionName("Delete")]
        [Authorize(Roles = RoleConst.ADMINISTRATOR)]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(DeleteFunctionViewModel model)
        {
            var function = await SystemFunctionManager.GetAsync(model.Id);
            var result = await SystemFunctionManager.DeleteAsync(function);
            if (result.Succeeded)
            {
                string url = Url.Action("Index");
                return Json(new {success = true, url = url});
            }
            AddErrors(result);
            return View(model);
        }

        /// <summary>
        /// 导航栏
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> Navbar()
        {
            List<NavbarFunctionViewModel> navbarList = new List<NavbarFunctionViewModel>();

            var identity = HttpContext.User.Identity;
            var functionList = SystemFunctionManager.GetFunctionsByRolesAsync(identity.GetUserId());
            var model = from function in await functionList
                orderby function.Order
                select function;
            foreach (var function in model)
            {
                navbarList.Add(new NavbarFunctionViewModel
                {
                    Id = function.Id,
                    Icon = function.Icon,
                    ParentId = function.ParentId,
                    ActionUrl = function.ActionUrl,
                    FunctionName = function.Name,
                    Type = function.Type
                });
            }

            //var controllers = await ActionHelper.GetControllersAsync(typeof (MvcApplication).Assembly);
            //foreach (var controller in controllers)
            //{
            //    if (navbarList.Any(m => m.ActionUrl == controller.ActionUrl))
            //        continue;
            //    NavbarFunctionViewModel parent = null;
            //    if (navbarList.Any(m => m.FunctionName == controller.ParentName))
            //        parent = navbarList.SingleOrDefault(p => p.FunctionName == controller.ParentName);
            //    int? parentId = null;
            //    if (parent != null)
            //    {
            //        parentId = parent.Id;
            //    }
            //    navbarList.Add(new NavbarFunctionViewModel
            //    {
            //        Id = -1,
            //        Icon = "",
            //        ParentId = parentId,
            //        FunctionName = controller.Name,
            //        ActionUrl = controller.ActionUrl,
            //        Type = EnumFunctionType.SystemFunction,

            //    });
            //}
            return View(navbarList);
        }



        private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error);
            }
        }
    }
}